home *** CD-ROM | disk | FTP | other *** search
/ Mac Power 1997 December / MACPOWER-1997-12.ISO.7z / MACPOWER-1997-12.ISO / AMUG / PROGRAMMING / Raven 1.2.sit / Raven 1.2 / Source / Foundation / OS / ZNotify.cpp < prev    next >
Text File  |  1997-08-07  |  5KB  |  208 lines

  1. /*
  2.  *  File:       ZNotify.cpp
  3.  *  Summary:       A wrapper around the Notification Manager.
  4.  *  Written by: Jesse Jones
  5.  *
  6.  *  Copyright ゥ 1996 Jesse Jones. 
  7.  *    For conditions of distribution and use, see copyright notice in ZTypes.h  
  8.  *
  9.  *  Change History (most recent first):    
  10.  *
  11.  *         <->     1/09/96    JDJ        Created
  12.  */
  13.  
  14. #include <ZNotify.h>
  15.  
  16. #include <Icons.h>
  17. #include <Resources.h>
  18.  
  19. #include <ZConstants.h>
  20. #include <ZExceptions.h>
  21. #include <ZMiscUtils.h>
  22. #include <ZProcess.h>
  23. #include <ZStringUtils.h>
  24.  
  25.  
  26. // ===================================================================================
  27. //    class TNotify
  28. // ===================================================================================
  29.  
  30. //----------------------------------------------------------------
  31. //
  32. // TNotify::~TNotify
  33. //
  34. //----------------------------------------------------------------
  35. TNotify::~TNotify()
  36. {
  37.     if (mInstalled)
  38.         NMRemove(&mRecord);
  39.  
  40.     if (mRecord.nmIcon != nil)
  41.         DisposeIconSuite(mRecord.nmIcon, false);
  42.         
  43.     if (mRecord.nmSound != nil && mRecord.nmSound != (Handle) -1)
  44.         ReleaseResource(mRecord.nmSound);
  45.  
  46.     if (mRecord.nmResp != nil)
  47.         DisposeRoutineDescriptor(mRecord.nmResp);
  48. }
  49.  
  50.  
  51. //----------------------------------------------------------------
  52. //
  53. // TNotify::TNotify (ResID, ResID, bool)
  54. //
  55. //----------------------------------------------------------------
  56. TNotify::TNotify(ResID iconID, ResID soundID, bool useMark)
  57. {
  58.     this->Init("", iconID, soundID, useMark);
  59. }
  60.  
  61.  
  62. //----------------------------------------------------------------
  63. //
  64. // TNotify::TNotify (string, ResID, ResID, bool)
  65. //
  66. //----------------------------------------------------------------
  67. TNotify::TNotify(const string& mesg, ResID iconID, ResID soundID, bool useMark)
  68. {
  69.     this->Init(mesg, iconID, soundID, useMark);
  70. }
  71.  
  72.  
  73. //----------------------------------------------------------------
  74. //
  75. // TNotify::TNotify (string, ResID)
  76. //
  77. //----------------------------------------------------------------
  78. TNotify::TNotify(const string& mesg, ResID soundID)
  79. {
  80.     this->Init(mesg, 0, soundID, false);
  81. }
  82.  
  83.                     
  84. //----------------------------------------------------------------
  85. //
  86. // TNotify::Init
  87. //
  88. //----------------------------------------------------------------
  89. void TNotify::Init(const string& mesg, ResID iconID, ResID soundID, bool useMark)
  90. {    
  91.     mRecord.nmIcon  = nil;
  92.     mRecord.nmSound = nil;
  93.     mRecord.nmResp  = nil;
  94.  
  95.     try {
  96.         mText = StrToPStr(mesg);
  97.         
  98.         mInstalled = false;
  99.         mCalledFromForeground = UProcess::InFront();
  100.         
  101.         // Initialize the notification manager record.
  102.         mRecord.qLink    = nil;
  103.         mRecord.qType    = nmType;
  104.         mRecord.nmMark   = useMark;
  105.         mRecord.nmStr    = mesg != "" ? mText : nil;
  106.         mRecord.nmRefCon = (long) this;
  107.  
  108.         // Create a handle for the icon.
  109.         if (iconID > 0) {
  110.             (void) GetIconSuite(&mRecord.nmIcon, iconID, svAllSmallData);
  111.         
  112.             ASSERT(mRecord.nmIcon != nil);
  113.  
  114.             if (mRecord.nmIcon != nil)                        // not worth throwing an exception for
  115.                 HNoPurge(mRecord.nmIcon);
  116.         }
  117.         
  118.         // Create a handle for the sound.
  119.         if (soundID > 0) {
  120.             mRecord.nmSound = GetResource('snd ', soundID);
  121.             ASSERT(mRecord.nmSound != nil);
  122.             
  123.             if (mRecord.nmSound != nil)                        // not worth throwing an exception for
  124.                 HNoPurge(mRecord.nmSound);
  125.         
  126.         } else if (soundID < 0)
  127.             mRecord.nmSound = (Handle) -1;
  128.  
  129.         // Create a upp for the notification callback.
  130.         mRecord.nmResp = NewNMProc(TNotify::DoCallback);
  131.         ThrowIfMemFail(mRecord.nmResp);
  132.         
  133.         // Register with the state broadcaster so we can find out when we're
  134.         // switched back in (we have to wait until we're switched to the front
  135.         // before we remove the notification since we want the icon to keep
  136.         // blinking).
  137.         if (!mCalledFromForeground)
  138.             TStateBroadcaster::Instance()->AddListener(this);
  139.  
  140.     } catch (...) {
  141.         // this can be constructed from dicy places like Drag Manager callbacks
  142.         // so we'll eat all exceptions
  143.     }
  144. }
  145.  
  146.  
  147. //----------------------------------------------------------------
  148. //
  149. // TNotify::Post
  150. //
  151. //----------------------------------------------------------------
  152. void TNotify::Post()
  153. {
  154.     ASSERT(!mInstalled);
  155.     
  156.     OSErr err = NMInstall(&mRecord);
  157.     ASSERT(err == noErr);
  158.     
  159.     mInstalled = err == noErr;
  160. }
  161.  
  162.  
  163. //----------------------------------------------------------------
  164. //
  165. // TNotify::HandleCallback
  166. //
  167. //----------------------------------------------------------------
  168. void TNotify::HandleCallback()
  169. {
  170.     this->OnCallback();
  171.     
  172.     if (mCalledFromForeground)
  173.         delete this;
  174. }
  175.  
  176.  
  177. //----------------------------------------------------------------
  178. //
  179. // TNotify::OnBroadcast
  180. //
  181. //----------------------------------------------------------------
  182. void TNotify::OnBroadcast(const SStateMessage& message)
  183. {
  184.     ASSERT(!mCalledFromForeground);
  185.  
  186.     if (message.mesg == kResumingApp)
  187.         delete this;
  188. }
  189.  
  190.  
  191. //----------------------------------------------------------------
  192. //
  193. // TNotify::DoCallback                                    [static]
  194. //
  195. //----------------------------------------------------------------
  196. pascal void TNotify::DoCallback(NMRec* record)
  197. {
  198.     try {
  199.         TNotify* thisPtr = reinterpret_cast<TNotify*>(record->nmRefCon);
  200.         
  201.         thisPtr->HandleCallback();
  202.     
  203.     } catch (...) {
  204.         // can't throw in a callback!
  205.     }
  206. }
  207.  
  208.